﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using OEMP.Util;
using OEMP.Util.Page;

namespace OEMP.Model
{
    /// <summary>
    /// 基础Model，所以model继承
    /// </summary>
    class _BaseModel : Hashtable
    {

        private const string SORT = "sort";
        private const string ORDER = "order";
        //排序语名字段
        private const string ORDER_BY = "ORDER_BY";
        private const string PAGESTART = "pagestart";
        private const string PAGE = "page";
        private const string ROWS = "rows";

        protected const String ORDER_ASC = "asc";
        protected const String ORDER_DESC = "desc";
        public _BaseModel()
            : base()
        {
            init();

        }

        public _BaseModel(int capacity)
            : base(capacity)
        {
            init();
        }

        public _BaseModel(IDictionary<string, object> m)
        {
            init();
            PutAll(m);
        }

        public _BaseModel(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {

        }

        private void init()
        {
            //this[ORDER_BY] = "ORDER BY 1";
            //this[ROWS] = SimplePage.DEF_COUNT;
            //this[PAGE] = 1;
        }

        public object this[string key]
        {
            get
            {
                return base[key];
            }
            set
            {
                base[key] = value is DateTime ? ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss") : value;
                if (key == SORT || key == ORDER)
                {
                    base[ORDER_BY] = GetOrderBy();
                }
            }
        }

        private string GetOrderBy()
        {
            string sort = GetString(SORT);
            if (!string.IsNullOrEmpty(sort))
            {
                StringUtils.AssertSQLField(sort);
                StringBuilder sb = new StringBuilder();
                sb.Append(" ORDER BY ");
                String[] n = sort.Split(',');
                String[] no = null;
                string order = GetString(ORDER);
                if (!string.IsNullOrEmpty(order))
                {
                    StringUtils.AssertSQLField(order);
                    no = order.Split(',');
                }
                for (int i = 0; i < n.Length; i++)
                {
                    if (i != 0)
                    {
                        sb.Append(",");
                    }
                    sb.Append(n[i]);
                    if (no != null && no.Length > i)
                    {
                        sb.Append(" ").Append(no[i]);
                    }
                }
                return sb.ToString();
            }
            return " ORDER BY 1";
        }

        public int Page
        {
            set { this[PAGE] = value; }
            get
            {
                int? page = GetInt(PAGE);
                return page.HasValue ? page.Value : 1;
            }
        }

        public int Rows
        {
            set { this[ROWS] = value; }
            get
            {
                int? rows = GetInt(ROWS);
                return rows.HasValue ? rows.Value : SimplePage.DEF_COUNT;
            }
        }

        public string Sort
        {
            get { return GetString(SORT); }
            set { this[SORT] = value; }
        }

        public string Order
        {
            get { return GetString(ORDER); }
            set { this[ORDER] = value; }
        }

        public string OrderBy
        {
            get { return GetString(ORDER_BY); }
        }

        private object GetObject(string key)
        {
            return this[key];
        }

        public string GetString(string key)
        {
            if (this.ContainsKey(key))
            {
                return this[key] == null ? "" : this[key].ToString();
            }
            return null;
        }
        
        public int? GetInt(string key)
        {
            if (this.ContainsKey(key))
            {
                if(this[key] == null||this[key].ToString() == ""){
                     return null;
                }
                return int.Parse(this[key].ToString());
            }
            return null;
        }

        public bool GetBool(string key)
        {
            if (this.ContainsKey(key))
            {
                return this[key] == null || this[key].ToString() == "" ? default(bool) : bool.Parse(this[key].ToString());
            }
            return false;
        }

        public bool GetBit(string key)
        {
            if (this.ContainsKey(key))
            {
                return this[key] == null || this[key].ToString() == "" ? default(bool) : bool.Parse(this[key].ToString());
            }
            return false;
        }

        public long? GetLong(string key)
        {
            if (this.ContainsKey(key))
            {
                if (this[key] == null || this[key].ToString() == "")
                {
                    return null;
                }
                return long.Parse(this[key].ToString());
            }
            return null;
        }

        public double? GetDouble(string key)
        {
            if (this.ContainsKey(key))
            {
                if (this[key] == null || this[key].ToString() == "")
                {
                    return null;
                }
                return double.Parse(this[key].ToString());
            }
            return null;
        }

        public decimal? GetDecimal(string key)
        {
            if (this.ContainsKey(key))
            {
                if (this[key] == null || this[key].ToString() == "")
                {
                    return null;
                }
                return decimal.Parse(this[key].ToString());
            }
            return null;
        }

        public DateTime? GetDateTime(string key)
        {
            if (this.ContainsKey(key))
            {
                if (this[key] == null || this[key].ToString() == "") return default(DateTime);
                if (this[key] is DateTime)
                {
                    return (DateTime)this[key];
                }
                return DateTime.Parse(this[key].ToString());
            }
            return null;
        }

        public void PutAll(IDictionary<string, object> dict)
        {
            foreach (KeyValuePair<string, object> e in dict)
            {
                this[e.Key] = e.Value;
            }
        }

        public void PutAll(Hashtable table)
        {
            foreach (KeyValuePair<string, object> e in table)
            {
                this[e.Key] = e.Value;
            }
        }
    }
}